import multiprocessing
import random
import time


def producer(queue, stop_event, id):
    """生产者函数，将随机数放入队列直到接收到停止事件"""
    while not stop_event.is_set():  # 检查停止事件是否被设置
        item = random.randint(1, 100)
        print(f'生产者 {id} 放入 {item}')
        queue.put(item)
        time.sleep(random.random())  # 模拟耗时操作


def consumer(queue):
    """消费者函数，从队列中取出数据并打印，直到接收到结束信号"""
    while True:
        item = queue.get()
        if item is None:  # 使用None作为结束信号（但在这个例子中我们不会从生产者发送None）
            print("消费者收到结束信号，停止消费......")
            break
        print(f'消费者取出 {item}')
        queue.task_done()  # 表示队列中的一项任务已被处理完成


if __name__ == '__main__':
    queue = multiprocessing.Queue()
    stop_event = multiprocessing.Event()  # 创建一个事件对象

    # 创建并启动生产者进程
    producers = [multiprocessing.Process(target=producer, args=(queue, stop_event, i)) for i in range(3)]
    for p in producers:
        p.start()

        # 创建一个消费者进程
    consumer_process = multiprocessing.Process(target=consumer, args=(queue,))
    consumer_process.start()

    # 等待一段时间以生成一些数据，然后设置停止事件
    time.sleep(5)
    print("结束生产")
    stop_event.set()  # 设置停止事件

    # 等待消费者处理完所有队列中的项目
    consumer_process.join()

    # 注意：生产者进程将在检查到停止事件时自行退出，因此我们不需要显式地等待它们

    print("所有进程都已结束")